use chrono::{DateTime,Utc,FixedOffset};
use failure::{Error, ensure};

pub type Date = chrono::Date<Utc>;

pub fn from_yymmdd(s: &str) -> Result<Date, Error> {
    let datetime: DateTime<Utc> = DateTime::from_utc(
        DateTime::<FixedOffset>::parse_from_str(s, "%y%m%d")
            ?
            .naive_utc(),
        Utc,
    );
    Ok(datetime.date())
}

pub fn to_yymmdd(date: &Date) -> String {
    date.format("%y%m%d").to_string()
}

/// e.g. "091011-091013,080301"
pub fn dates_from_str(s: &str) -> Result<Vec<Date>, Error> {
    let mut vec = Vec::new();
    for slice in s.split(',') {
        if slice.len()==6 {
            vec.push(from_yymmdd(slice)?);
        } else {
            ensure!(slice.len()==13, "dates string error");
            ensure!(s.as_bytes()[6]==b'-', "dates string error");
            let d1 = from_yymmdd(&s[..6])?;
            let d2 = from_yymmdd(&s[7..])?;
            ensure!(d1 <= d2, "start_date > end_date");
            let mut d = d1;
            while d <= d2 {
                vec.push(d);
                d = d.succ();
            }
        }
    }
    Ok(vec)
}
